package main

import "fmt"

/*
*
Go匿名字段：可以像字段成员那样访问匿名字段方法，编译器负责查找。
结构体有匿名字段，如果在结构体上直接调用定义在其匿名结构体字段上的方法，也是可行的。编译器会自己查找。
*/

//type User struct {
//	id   int
//	name string
//}
//
//type Manager struct {
//	User //结构体的匿名字段，没有字段名，只有类型
//}
//
//func (self *User) ToString() string { //在结构体User上定义一个方法ToString，receiver = &(Manager.User)
//	return fmt.Sprintf("User: %p, %v", self, self)
//}
//
//func main() {
//	m := Manager{User{1, "Tom"}} //实例化一个Manager结构体
//	fmt.Printf("Manager: %p\n", &m)
//	fmt.Println(m.ToString()) //在结构体Manager上调用结构体User的方法
//}

/**
通过匿名字段，可获得和集成类的的复用能力，依据编译器查找次序，只需在外层定义同层方法，就可以实现 override

*/

type User struct {
	id   int
	name string
}

type Manager struct {
	User
	title string
}

func (self *User) ToString() string {
	return fmt.Sprintf("User: %p, %v", self, self)
}

func (self *Manager) ToString() string {
	return fmt.Sprintf("Manager: %p, %v", self, self)
}

func main() {
	m := Manager{User{1, "Tom"}, "Administrator"}

	fmt.Println(m.ToString())

	fmt.Println(m.User.ToString())
}

/**
注意，9_结构体 Manager 与其儿子结构体User上都定义了方法toString() (同名方法)，这就拥有了和集成类似的复用能力。
*/
